package com.zxx.casserver.modules.org.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.zxx.cascommon.base.exception.DataAlreadyExistException;
import com.zxx.cascommon.base.exception.DataNoChangeException;
import com.zxx.cascommon.base.exception.DataNotExistException;
import com.zxx.cascommon.base.exception.ParamsException;
import com.zxx.casserver.base.common.UserConstants;
import com.zxx.casserver.modules.org.entity.OrgDO;
import com.zxx.casserver.modules.org.entity.OrgVO;
import com.zxx.casserver.modules.org.mapper.OrgMapper;
import com.zxx.casserver.modules.org.service.IOrgService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * <p>
 * 组织机构表 服务实现类
 * </p>
 *
 * @author zhoukai
 * @since 2022-07-14
 */
@Service
public class OrgServiceImpl extends ServiceImpl<OrgMapper, OrgDO> implements IOrgService {

    @Override
    public Set<Long> getOrgIdByName(String orgName) {
        QueryWrapper<OrgDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name", orgName);
        List<OrgDO> orgList = list(queryWrapper);
        if (ObjectUtils.isEmpty(orgList)) {
            return null;
        }
        Set<Long> orgSet = new HashSet<>();
        for (OrgDO orgDO : orgList) {
            orgSet.add(orgDO.getOrgId());
        }
        return orgSet;
    }

    @Override
    public IPage<OrgDO> listOrg(OrgVO orgVO) {
        Page<OrgDO> page = new Page<>(orgVO.getCurPage(), orgVO.getPageSize());
        QueryWrapper<OrgDO> queryWrapper = new QueryWrapper<>();

        if (!ObjectUtils.isEmpty(orgVO.getPlatformName())) {
            Set<Long> platformIdSet = getOrgIdByName(orgVO.getPlatformName());
            if (!ObjectUtils.isEmpty(platformIdSet)) {
                queryWrapper.in("platform_id", platformIdSet);
            }
        }
        if (!ObjectUtils.isEmpty(orgVO.getIds())) {
            queryWrapper.in("org_id", orgVO.getIds());
        }
        if (!ObjectUtils.isEmpty(orgVO.getOrgId())) {
            queryWrapper.eq("org_id", orgVO.getOrgId());
        }
        if (!ObjectUtils.isEmpty(orgVO.getName())) {
            queryWrapper.like("name", orgVO.getName());
        }
        if (!ObjectUtils.isEmpty(orgVO.getAppId())) {
            queryWrapper.eq("app_id", orgVO.getAppId());
        }
        if (!ObjectUtils.isEmpty(orgVO.getPlatformId())) {
            queryWrapper.eq("platform_id", orgVO.getPlatformId());
        }
        if (!ObjectUtils.isEmpty(orgVO.getStatus())) {
            queryWrapper.eq("status", orgVO.getStatus());
        }
        if (!ObjectUtils.isEmpty(orgVO.getArea())) {
            queryWrapper.eq("area", orgVO.getArea());
        }
        if (!ObjectUtils.isEmpty(orgVO.getCity())) {
            queryWrapper.eq("city", orgVO.getCity());
        }
        if (!ObjectUtils.isEmpty(orgVO.getStartTime())) {
            queryWrapper.ge("create_time", orgVO.getStartTime());
        }
        if (!ObjectUtils.isEmpty(orgVO.getEndTime())) {
            queryWrapper.le("create_time", orgVO.getEndTime());
        }
        if (!ObjectUtils.isEmpty(orgVO.getColumns()) && !ObjectUtils.isEmpty(orgVO.getAsc())) {
            String columnNames = Joiner.on(",").join(orgVO.getColumns());
            if (orgVO.getAsc()) {
                queryWrapper.orderByAsc(columnNames);
            } else {
                queryWrapper.orderByDesc(columnNames);
            }
        } else {
            queryWrapper.orderByDesc("create_time");
        }
        return page(page, queryWrapper);
    }


    @Override
    public IPage<OrgVO> dispose(IPage<OrgDO> page) {
        //获取所属平台的ID
        Set<Long> orgIdSet = new HashSet<>();
        //拼接所属平台名称
        if (!ObjectUtils.isEmpty(page.getRecords())) {
            for (OrgDO orgDO : page.getRecords()) {
                orgIdSet.add(orgDO.getPlatformId());
            }
        }
        //用来保存组织与名称的值
        Map<Long, String> orgMap = new HashMap<>(64);
        //根据组织ID批量查询组织信息，拼接对应的组织名称回去
        if (!ObjectUtils.isEmpty(orgIdSet)) {
            List<OrgDO> orgList = listByIds(orgIdSet);
            if (ObjectUtils.isEmpty(orgList)) {
                for (OrgDO orgDO : orgList) {
                    orgMap.put(orgDO.getOrgId(), orgDO.getName());
                }
            }
        }

        List<OrgVO> orgList = new ArrayList<>(32);
        for (OrgDO orgDO : page.getRecords()) {
            OrgVO orgVO = JSON.parseObject(JSON.toJSONString(orgDO), OrgVO.class);
            orgVO.setPlatformName(orgMap.get(orgDO.getPlatformId()));
            orgList.add(orgVO);
        }

        IPage<OrgVO> orgPage = new Page<>();
        orgPage.setCurrent(page.getCurrent());
        orgPage.setPages(page.getPages());
        orgPage.setTotal(page.getTotal());
        orgPage.setSize(page.getSize());
        orgPage.setRecords(orgList);
        return orgPage;
    }

    @Override
    public OrgDO saveOrg(OrgVO orgVO) {
        //判断组织名称是否存在
        QueryWrapper<OrgDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", orgVO.getName());
        List<OrgDO> oldOrgList = list(queryWrapper);
        if (!ObjectUtils.isEmpty(oldOrgList)) {
            throw new DataAlreadyExistException();
        }

        OrgDO orgDO = JSON.parseObject(JSON.toJSONString(orgVO), OrgDO.class);
        orgDO.setCreateTime(System.currentTimeMillis());
        orgDO.setUpdateTime(System.currentTimeMillis());

        if (ObjectUtils.isEmpty(orgVO.getParentId())
                || UserConstants.PERMISSION_ROOT.equals(orgVO.getPlatformName())) {
            orgDO.setParentId(Long.valueOf(UserConstants.PERMISSION_ROOT));
            orgDO.setParentIds("[" + orgVO.getOrgId() + "]");
        } else {
            //查询上级节点
            OrgDO parentOrg = getById(orgDO.getParentId());
            if (ObjectUtils.isEmpty(parentOrg)) {
                throw new DataNotExistException();
            }
            orgDO.setParentIds(orgDO.getParentIds() + ",[" + orgDO.getOrgId() + "]");
            orgDO.setLevel(orgDO.getLevel() + 1);
        }

        boolean isSave = save(orgDO);
        if (!isSave) {
            return null;
        }
        return orgDO;
    }

    @Override
    public OrgDO updateOrg(OrgVO orgVO) {
        //判断当前组织是否存在
        OrgDO oldOrgDO = getById(orgVO.getOrgId());
        if (ObjectUtils.isEmpty(oldOrgDO)) {
            throw new DataNotExistException();
        }
        OrgDO orgDO = checkChange(orgVO, oldOrgDO);
        if (ObjectUtils.isEmpty(orgDO)) {
            throw new DataNoChangeException();
        }
        boolean isUpdate = updateById(orgDO);
        if (isUpdate) {
            return orgDO;
        }
        return null;
    }

    @Override
    public Boolean deleteOrg(OrgVO orgVO) {
        //判断当前组织是否存在
        OrgDO oldOrgDO = getById(orgVO.getOrgId());
        if (ObjectUtils.isEmpty(oldOrgDO)) {
            throw new DataNotExistException();
        }
        //判断当前组织是否有关联关系，如果有则，不能删除
        QueryWrapper<OrgDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", oldOrgDO.getOrgId());
        List<OrgDO> orgList = list(queryWrapper);
        if (!ObjectUtils.isEmpty(orgList)) {
            throw new ParamsException("当前组织被其他组织关联，不可删除");
        }
        return removeById(oldOrgDO);
    }

    @Override
    public List<OrgDO> getOrgTree(OrgVO orgVO) {
        QueryWrapper<OrgDO> queryWrapper = new QueryWrapper<>();
        if (ObjectUtils.isEmpty(orgVO.getParentId())) {
            queryWrapper.eq("parent_id", orgVO.getParentId());
        }
        if (ObjectUtils.isEmpty(orgVO.getLevel())) {
            queryWrapper.eq("level", orgVO.getLevel());
        }
        return list(queryWrapper);
    }


    /**
     * 判断组织是否有变化
     *
     * @param orgVO
     * @param oldOrgDO
     * @return 返回有变化的字段
     */
    private OrgDO checkChange(OrgVO orgVO, OrgDO oldOrgDO) {
        OrgDO orgDO = new OrgDO();
        orgDO.setOrgId(orgVO.getOrgId());
        orgDO.setAppId(orgVO.getAppId());
        orgDO.setUpdateTime(System.currentTimeMillis());

        boolean isChange = false;

        //如果变更name，需要判断名字在当前系统下是否已经存在
        if (!ObjectUtils.isEmpty(orgVO.getName()) && !orgVO.getName().equals(oldOrgDO.getName())) {
            QueryWrapper<OrgDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("app_id", oldOrgDO.getAppId());
            queryWrapper.eq("name", orgVO.getName());
            queryWrapper.notIn("org_id", oldOrgDO.getOrgId());
            List<OrgDO> orgList = list(queryWrapper);
            if (!ObjectUtils.isEmpty(orgList)) {
                throw new ParamsException("当前组织名称在该系统下已经存在，不可编辑");
            }
            orgDO.setName(orgVO.getName());
            isChange = true;
        }

        //判断是否变更上级节点，如果上级节点变更，则需要重新变更
        if (!ObjectUtils.isEmpty(orgVO.getParentId()) &&
                !orgVO.getParentId().equals(orgDO.getParentId())) {
            //查询上级节点
            OrgDO parentOrg = getById(orgDO.getParentId());
            if (ObjectUtils.isEmpty(parentOrg)) {
                throw new DataNotExistException();
            }
            orgDO.setParentIds(orgDO.getParentIds() + ",[" + orgDO.getOrgId() + "]");
            orgDO.setLevel(orgDO.getLevel() + 1);
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(orgVO.getSort()) && !orgVO.getSort().equals(oldOrgDO.getSort())) {
            orgDO.setSort(orgVO.getSort());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(orgVO.getPlatformId()) && !orgVO.getPlatformId().equals(oldOrgDO.getPlatformId())) {
            orgDO.setPlatformId(orgVO.getPlatformId());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(orgVO.getOrgType()) && !orgVO.getOrgType().equals(oldOrgDO.getOrgType())) {
            orgDO.setOrgType(orgVO.getOrgType());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(orgVO.getProvince()) && !orgVO.getProvince().equals(oldOrgDO.getProvince())) {
            orgDO.setProvince(orgVO.getProvince());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(orgVO.getArea()) && !orgVO.getArea().equals(oldOrgDO.getArea())) {
            orgDO.setArea(orgVO.getArea());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(orgVO.getCity()) && !orgVO.getCity().equals(oldOrgDO.getCity())) {
            orgDO.setCity(orgVO.getCity());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(orgVO.getStatus()) && !orgVO.getStatus().equals(oldOrgDO.getStatus())) {
            orgDO.setStatus(orgVO.getStatus());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(orgVO.getRemark()) && !orgVO.getRemark().equals(oldOrgDO.getRemark())) {
            orgDO.setRemark(orgVO.getRemark());
            isChange = true;
        }

        return isChange ? orgDO : null;
    }
}
